package com.neusoft.tools;

import java.time.LocalDate;
import java.time.format.DateTimeParseException;

/**
 * 一个用于验证用户输入的工具类.
 */
public class ValidationUtils {

    /**
     * 验证用户输入.
     *
     * @param str 要检查的字符串
     * @return 如果字符串为 null、为空或仅包含空白，则返回 true；否则返回 false。
     */
    public static boolean isNullOrBlank(String str) {
        return str == null || str.isBlank();
    }

    /**
     * 验证用户输入.
     *
     * @param str 要检查的字符串
     * @return 如果字符串包含空格，则返回true，否则返回false。
     */
    public static boolean containBlank(String str) {
        if (str == null) {
            return false;
        }
        return str.trim().length() != str.length();
    }

    /**
     * 验证用户输入
     *
     * @param str 要检查的字符串
     * @return 如果字符串完全由中文或英文字母组成，则返回 true；否则（包括 null、空字符串）返回 false。
     */
    public static boolean isChineseOrLetter(String str) {
        if (isNullOrBlank(str)) {
            return false;
        }

        // 将字符串转换为字符数组，并逐个检查
        for (char c : str.toCharArray()) {
            // 判断字符是否为英文字母
            boolean isLetter = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
            // 判断字符是否为常用中文字符
            boolean isChinese = c >= '\u4e00' && c <= '\u9fa5';

            if (!isLetter && !isChinese) {
                return false;
            }
        }

        return true;
    }

    /**
     * 验证用户输入
     *
     * @param str 要检查的字符串，通常用于座机号码格式验证
     * @return 如果字符串完全由数字或连字符组成，则返回 true；否则（包括 null、空字符串）返回 false。
     */
    public static boolean isDigitOrHyphen(String str) {
        if (isNullOrBlank(str)) {
            return false;
        }

        for (char c : str.toCharArray()) {
            boolean isDigit = Character.isDigit(c);
            // 判断字符是否为连字符
            boolean isHyphen = c == '-';
            if (!isDigit && !isHyphen) {
                return false;
            }
        }
        return true;
    }
    /**
     * 对日期字符串预处理
     *
     * @param dateStr 原始日期字符串
     * @return 处理后的字符串，若格式不符合预期则返回null
     */
    private static String preprocessDateString(String dateStr) {
        // 使用连字符分割字符串
        String[] parts = dateStr.split("-");

        if (parts.length != 3) {
            return null;
        }

        try {
            String yearPart = parts[0];
            String monthPart = parts[1];
            String dayPart = parts[2];
            // 验证年份格式
            if (!yearPart.matches("\\d{4}")) {
                return null;
            }

            // 补全月份为两位数字
            String formattedMonth = formatNumberPart(monthPart, 2);
            if (formattedMonth == null) {
                return null;
            }

            // 补全日期为两位数字
            String formattedDay = formatNumberPart(dayPart, 2);
            if (formattedDay == null) {
                return null;
            }

            return yearPart + "-" + formattedMonth + "-" + formattedDay;
        } catch (Exception e) {
            return null;
        }
    }
        /**
         * 验证用户输入
         *
         * @param dateStr 要检查的日期字符串
         * @return 如果字符串是有效的 YYYY-MM-DD 日期，则返回 true；否则返回 false。
         */
        public static boolean isYYYYMMDD(String dateStr) {
            // 首先，检查字符串是否为 null 或空
            if (isNullOrBlank(dateStr)) {
                return false;
            }
            // 将字符串转换为字符数组，并逐个检查
            String processedDate = preprocessDateString(dateStr);
            if (processedDate == null) {
                return false;
            }
            try {
                LocalDate.parse(processedDate);
            } catch (DateTimeParseException e) {
                return false;
            }

            return true;
        }
    /**
     * 将数字字符串补全到指定长度，不足的左补零
     *
     * @param numStr 数字字符串
     * @param length 目标长度
     * @return 补全后的字符串，若输入不合法则返回null
     */
    private static String formatNumberPart(String numStr, int length) {
        // 验证是否只包含数字
        if (!numStr.matches("\\d+")) {
            return null;
        }
        // 验证数字位数是否在合理范围内
        int numValue = Integer.parseInt(numStr);
        if (numValue < 0 || numStr.length() > length) {
            return null;
        }
        // 使用String.format补全前导零
        return String.format("%0" + length + "d", numValue);
    }
    /**
     * 验证用户输入
     *
     * @param str 要检查的字符串，例如密码.
     * @return 如果字符串中包含至少一个中文字符, 则返回 {@code true}; 否则返回 {@code false}.
     * 如果输入为 null 或空字符串, 也返回 {@code false}.
     */
    public static boolean containsChinese(String str) {
        if (str == null || str.isEmpty()) {
            return false;
        }
        // 遍历字符串中的每一个字符
        for (char c : str.toCharArray()) {
            if (c >= '\u4e00' && c <= '\u9fa5') {
                // 一旦发现中文字符，立即返回true
                return true;
            }
        }

        return false;
    }
}